package cn.initcap.algorithm.swing.animation;

import cn.initcap.algorithm.swing.AlgoVisHelper;
import cn.initcap.algorithm.swing.BaseAlgoFrame;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

/**
 * @author initcap
 * @date 2018/8/3 AM9:43
 */
public class AlgoVisualizer {

    private Circle[] circles;
    private BaseAlgoFrame frame;
    private boolean isAnimated = true;

    public AlgoVisualizer(int sceneWidth, int sceneHeight, int n) {

        // 初始化数据
        circles = new Circle[n];
        int r = 50;
        for (int i = 0; i < n; i++) {
            int x = new Random().nextInt(sceneWidth - 2 * r) + r;
            int y = new Random().nextInt(sceneHeight - 2 * r) + r;
            int vx = new Random().nextInt(11) - 5;
            int vy = new Random().nextInt(11) - 5;
            circles[i] = new Circle(x, y, r, vx, vy);
        }

        // 初始化视图
        EventQueue.invokeLater(() -> {
            frame = new BaseAlgoFrame("Welcome", sceneWidth, sceneHeight) {
                @Override
                public void draw(Graphics graphics) {
                    Graphics2D g2d = (Graphics2D) graphics;
                    AlgoVisHelper.setStrokeWidth(g2d, 1);
                    AlgoVisHelper.setColor(g2d, Color.RED);
                    for (Circle circle : circles) {
                        if (circle.isFilled) {
                            AlgoVisHelper.fillCircle(g2d, circle.x, circle.y, circle.getR());
                        } else {
                            AlgoVisHelper.strokeCircle(g2d, circle.x, circle.y, circle.getR());
                        }
                    }
                }
            };
            frame.addKeyListener(new AlgoKeyListener());
            frame.addMouseListener(new AlgoMouseListener());
            new Thread(() -> run()).start();
        });
    }

    public static void main(String[] args) {

        int sceneWidth = 800;
        int sceneHeight = 800;
        int n = 10;

        new AlgoVisualizer(sceneWidth, sceneHeight, n);
    }

    /**
     * 动画逻辑
     */
    private void run() {

        while (true) {
            // 绘制数据
            frame.render(circles);
            AlgoVisHelper.pause(20);

            // 更新数据
            if (isAnimated) {
                for (Circle circle : circles) {
                    circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
                }
            }
        }
    }

    private class AlgoKeyListener extends KeyAdapter {

        @Override
        public void keyReleased(KeyEvent event) {
            if (event.getKeyChar() == ' ') {
                isAnimated = !isAnimated;
            }
        }
    }

    private class AlgoMouseListener extends MouseAdapter {

        @Override
        public void mouseReleased(MouseEvent event) {

            event.translatePoint(
                    0,
                    -(frame.getBounds().height - frame.getCanvasHeight())
            );
            for (Circle circle : circles) {
                if (circle.contain(event.getPoint())) {
                    circle.isFilled = !circle.isFilled;
                }
            }
        }
    }
}
